package likou.Thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.function.IntConsumer;

/**
 * @description:
 * @title: ZeroEvenOdd
 * @author: zp
 * @date: 2021/8/28 21:04
 * 打印零与奇偶数
 */
class ZeroEvenOdd {
    private int n;
    private volatile int start = 1;
    private volatile int state;
    private Lock lock=new ReentrantLock();
    private Condition zero = lock.newCondition();
    private Condition even = lock.newCondition();
    private Condition odd = lock.newCondition();

    public ZeroEvenOdd(int n) {
        this.n = n;
    }

    // 为0
    public void zero(IntConsumer printNumber) throws InterruptedException {
            lock.lock();
            try {
                while (start <= n){
                    //线程等待
                    if(state != 0){
                        zero.await();
                    }
                    printNumber.accept(0);

                    if(start % 2 == 0){
                        state = 2 ;
                        even.signal();
                    }else{
                        state = 1;
                        odd.signal();
                    }
                    zero.await();
                }
                even.signal();
                odd.signal();
            }catch (Exception e){
                e.getStackTrace();
            }finally {
                lock.unlock();
            }

    }
    //偶数
    public void even(IntConsumer printNumber) throws InterruptedException {
            lock.lock();
            try {
                while (start <= n) {
                    //线程等待
                    if(state != 2){
                        even.await();
                    }else {
                        printNumber.accept(start++);
                        state = 0;
                        zero.signal();
                    }
                }
            } catch (Exception e) {
                e.getStackTrace();
            } finally {
                lock.unlock();
            }
    }
    //奇数
    public void odd(IntConsumer printNumber) throws InterruptedException {
            lock.lock();
            try {
                while (start<=n) {
                    //线程等待
                    if(state != 1){
                        odd.await();
                    }else {
                        printNumber.accept(start++);
                        state = 0;
                        zero.signal();
                    }
                }
            } catch (Exception e) {
                e.getStackTrace();
            } finally {
                lock.unlock();
            }
    }
}
